package com.common.domainService;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.applicationLayer.formbean.ListPathForm;
import com.applicationLayer.formbean.PathForm;
import com.applicationLayer.formbean.RegistrationForm;
import com.applicationLayer.formbean.SearchingPathForm;
import com.common.DAO.ICovoitureurDAO;
import com.common.DAO.IPathDAO;
import com.common.DAO.IRegistrationDAO;
import com.common.DAO.IStepDAO;
import com.common.DAO.ITownDAO;
import com.common.entity.Covoitureur;
import com.common.entity.Path;
import com.common.entity.Registration;
import com.common.entity.Town;
import com.common.transformer.ListPathTransformer;
import com.common.transformer.PathTransformer;
import com.common.transformer.RegistrationTransformer;

public class PathService implements IPathService  {
	Logger logger = Logger.getLogger(PathService.class);
	private IPathDAO pathDAO;
	public ICovoitureurDAO getCovoitureurDAO() {
		return covoitureurDAO;
	}


	public void setCovoitureurDAO(ICovoitureurDAO covoitureurDAO) {
		this.covoitureurDAO = covoitureurDAO;
	}

	private ITownDAO townDAO;
	private IRegistrationDAO registrationDAO;
	private ICovoitureurDAO covoitureurDAO;
	private IStepDAO stepDAO;

	public IStepDAO getStepDAO() {
		return stepDAO;
	}

	public void setStepDAO(IStepDAO stepDAO) {
		this.stepDAO = stepDAO;
	}

	public IRegistrationDAO getRegistrationDAO() {
		return registrationDAO;
	}

	public void setRegistrationDAO(IRegistrationDAO registrationDAO) {
		this.registrationDAO = registrationDAO;
	}


	public List<ListPathForm> PathList(){
		List<ListPathForm> listPathForm =new ArrayList<ListPathForm>();
		try{
			
			List<Path> listPath=this.getPathDAO().list();
			if(listPath!=null)
			//Transformation de la listAdmin en listAdminForm pour action
			for(Path path : listPath){
				listPathForm.add(ListPathTransformer.Path_TO_ListPathForm(path, townDAO.getTownByid(path.getArrival_town()).getName(),townDAO.getTownByid(path.getDepart_town()).getName()));
			}
		}catch (Exception e) {
			logger.error("Erreur methode list de PathSerivce",e);
			return null;
		}
		return listPathForm;
		
	}


	public IPathDAO getPathDAO() {
		return pathDAO;
	}


	public void setPathDAO(IPathDAO pathDAO) {
		this.pathDAO = pathDAO;
	}
	
	
	public ITownDAO getTownDAO() {
		return townDAO;
	}


	public void setTownDAO(ITownDAO townDAO) {
		this.townDAO = townDAO;
	}


	public List<ListPathForm> researchPath(SearchingPathForm searchingPathForm) {
		List<Town> listTownDeparture = this.getTownDAO().listTownByName(searchingPathForm.getDeparture());
		List<Town> listTownArrival = this.getTownDAO().listTownByName(searchingPathForm.getArrival());
		System.out.println("listTownDeparture : "+listTownDeparture);
		System.out.println("listTownArrival : "+listTownArrival);
		List<Path> path=null;
		if((!listTownDeparture.isEmpty() || StringUtils.isBlank(searchingPathForm.getDeparture())) && (!listTownArrival.isEmpty() || StringUtils.isBlank(searchingPathForm.getArrival()))){
			System.out.println("Passage dans if");
			path=this.getPathDAO().research(listTownDeparture, listTownArrival, searchingPathForm.getDate());
		}
		List<ListPathForm> pathFormList=new ArrayList<ListPathForm>();
		if(path != null){
			for(Path current :path){
				pathFormList.add(new ListPathForm(current,townDAO.getTownByid(current.getDepart_town()).getName(),townDAO.getTownByid(current.getArrival_town()).getName()));
			}
		}
		
		return pathFormList;
	}
	
	public List<ListPathForm> getLastPath(){
		List<ListPathForm> pathList = null;
		List<Path> paths=null;
		paths = pathDAO.listLastPath();
		if(paths != null){
			pathList = new ArrayList<ListPathForm>();
			for(Path p :paths){
				pathList.add(ListPathTransformer.Path_TO_ListPathForm(p, townDAO.getTownByid(p.getArrival_town()).getName(),townDAO.getTownByid(p.getDepart_town()).getName()));
			}
		}
		return pathList;
	}
	
	public List<ListPathForm> getDefaultPath(int id_ville) {
		List<ListPathForm> pathList = null;
		List<Path> paths=null;
		paths = pathDAO.listDefaultPath(id_ville);
		if(paths != null){
			pathList = new ArrayList<ListPathForm>();
			for(Path p :paths){
				pathList.add(ListPathTransformer.Path_TO_ListPathForm(p, townDAO.getTownByid(p.getArrival_town()).getName(),townDAO.getTownByid(p.getDepart_town()).getName()));
			}
		}
		return pathList;
	}

	public PathForm getPathById(int id_path) {
		Path p = pathDAO.getPathById(id_path);
		if(p==null) return null;
		Covoitureur co = covoitureurDAO.getCovoitureur(p.getDriver());
		String driver = co.getNom()+" "+co.getPrenom();
		return PathTransformer.Path_TO_PathForm(p,townDAO.getTownByid(p.getDepart_town()).getName(),townDAO.getTownByid(p.getArrival_town()).getName(),driver);
	}
	
	/**********************************************************
	 * create a path from a pathForm					      * 
	 **********************************************************/
	@Override
	public int createPath(PathForm pathForm) {
		Path path=PathTransformer.PathForm_TO_Path(pathForm);
		try{
			path = this.getPathDAO().addPath(path);
		}catch (Exception e) {
			logger.error("An error has occured in PathService while adding", e);
		}
		return path.getId_path();
	}


	@Override
	public void addCovoitureur(int id_covoitureur, PathForm pathForm) {
		Path path=PathTransformer.PathForm_TO_Path(pathForm);
		path.setNb_places(path.getNb_places()-1);
		try{
			pathDAO.update(path);
			RegistrationForm registrationForm= new RegistrationForm(pathForm.getId_path(),id_covoitureur);
			Registration registration = RegistrationTransformer.RegistrationForm_TO_Registration(registrationForm);
			registrationDAO.addRegistration(registration);
		}catch (Exception e) {
			logger.error("An error has occured in PathService while updating", e);
		}
	}


	@Override
	public List<ListPathForm> getPathForCovoitureurById(int id_covoitureur,boolean old) {
		List<ListPathForm> pathFormList = new ArrayList<ListPathForm>();
		List<Path> pathList = new ArrayList<Path>();
		List<Registration> registrationList=null;
		List<Integer> pathIds = new ArrayList<Integer>();
		try{
			registrationList=registrationDAO.listRegistrationByCovoitureurId(id_covoitureur);
			for(Registration r : registrationList)
				pathIds.add(r.getId_path());
			pathList = pathDAO.listPathByIds(pathIds,old);
			if(pathList !=null){
				for(Path p : pathList){
					pathFormList.add(ListPathTransformer.Path_TO_ListPathForm(p,townDAO.getTownByid(p.getArrival_town()).getName(),townDAO.getTownByid(p.getDepart_town()).getName()));
				}
			}
		}catch (Exception e) {
			logger.error("An error has occured in PathService while listing path", e);
		}
		return pathFormList;
	}


	@Override
	public boolean isCovoitureurRegisterForPath(int id_covoitureur, int id_path) {
		return registrationDAO.isCovoitureurRegisterForPath(id_covoitureur,id_path);
	}


	@Override
	public List<ListPathForm> getPathPostedByCovoitureurId(int id_covoitureur) {
		List<ListPathForm> pathList = null;
		List<Path> paths=null;
		paths = pathDAO.listPostedPathByCovoitureur(id_covoitureur);
		if(paths != null){
			pathList = new ArrayList<ListPathForm>();
			for(Path p :paths){
				pathList.add(ListPathTransformer.Path_TO_ListPathForm(p, townDAO.getTownByid(p.getArrival_town()).getName(), townDAO.getTownByid(p.getDepart_town()).getName()));
			}
		}
		return pathList;
	}
	
	@Override
	public void removeCovoitureur(int id_covoitureur, PathForm pa) {
		Path path=PathTransformer.PathForm_TO_Path(pa);
		path.setNb_places(path.getNb_places()+1);
		try{
			pathDAO.update(path);
			RegistrationForm registrationForm= new RegistrationForm(pa.getId_path(),id_covoitureur);
			Registration registration = RegistrationTransformer.RegistrationForm_TO_Registration(registrationForm);
			registrationDAO.removeRegistration(registration);
		}catch (Exception e) {
			logger.error("An error has occured in PathService while updating", e);
		}
	}
	
	/**********************************************************
	 *     Supprime un ou plusieur Id a partir d'une liste d'id
	 *     de type string id1,id2,...,idn
	 **********************************************************/
	@Override
	public void removePath(String listId) {
		System.out.println("removePath function");
		String[] tableId=listId.split(",");
		for(String id : tableId){
			System.out.println(id);
			id=id.trim();
			List<Registration> registrations = this.getRegistrationDAO().listRegistrationByPathId(Integer.parseInt(id));

			System.out.println("Remove registrations in Service, function removePath");
			for(Registration registr : registrations){
				System.out.println("registration covoit : "+registr.getId_covoitureur());
				this.getRegistrationDAO().removeRegistration(registr);
			}

			this.getStepDAO().removeStepByPath(Integer.parseInt(id));
			
			this.getPathDAO().removePath(Integer.parseInt(id));
		}
		
	}


	@Override
	public void editPath(PathForm pathForm) {
		Path path=PathTransformer.PathForm_TO_Path(pathForm);
		try{
			this.getPathDAO().editPath(path);
		}catch (Exception e) {
			logger.error("An error has occured in PathService while editing", e);
		}
	}

}
